﻿/*十六进制流加强类*/
namespace System.Data
{
    using System;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Helpers;
    using System.IO;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using System.Runtime.Serialization;
    using System.Threading;

    [Serializable]
    public class Bytes : IDisposable
    {
        public byte[] buffer;
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private int disposedFlag;
        public static Bytes Empty = new Bytes(new byte[0], false);
        public int len;
        public int offset;

        public Bytes()
        {
            this.disposedFlag = 1;
        }

        public Bytes(byte[] buffer, bool copy = false)
        {
            this.disposedFlag = 1;
            if (copy)
            {
                byte[] destinationArray = new byte[buffer.Length];
                Array.Copy(buffer, destinationArray, destinationArray.Length);
                buffer = destinationArray;
            }
            this.buffer = buffer;
            this.offset = 0;
            this.len = buffer.Length;
        }

        public Bytes(byte[] buffer, int offset, int len = -1, bool copy = false)
        {
            this.disposedFlag = 1;
            if (len == -1)
            {
                len = buffer.Length - offset;
            }
            if (copy)
            {
                byte[] destinationArray = new byte[len];
                Array.Copy(buffer, offset, destinationArray, 0, len);
                this.buffer = destinationArray;
                this.offset = 0;
                this.len = len;
            }
            else
            {
                this.buffer = buffer;
                this.offset = offset;
                this.len = len;
            }
        }

        //public Bytes Clone(bool copyBuffer = false)
        //{
        //    if (!copyBuffer)
        //    {
        //        return new Bytes(this.buffer, this.offset, this.len, false);
        //    }
        //    return new Bytes(this.buffer.Clone(this.offset, this.len), 0, -1, false);
        //}

        //public virtual void DeSerialize(Stream stream)
        //{
        //    this.len = stream.ReadInt32();
        //    this.buffer = new byte[this.len];
        //    stream.Read(this.buffer, 0, this.len);
        //}

        public void Dispose()
        {
            if (Interlocked.Exchange(ref this.disposedFlag, 0) == 1)
            {
                this.Dispose(true);
                GC.SuppressFinalize(this);
            }
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
            }
            this.buffer = null;
        }

        ~Bytes()
        {
            if (Interlocked.Exchange(ref this.disposedFlag, 0) == 1)
            {
                this.Dispose(false);
            }
        }

        public static implicit operator Bytes(byte[] buffer)
        {
            return new Bytes(buffer, false);
        }

        //public virtual void Serialize(Stream stream)
        //{
        //    stream.Write(this.len);
        //    stream.Write(this.buffer, this.offset, this.len);
        //}

        public void SetBuffer(byte[] buffer, int offset = 0, int len = -1, bool copy = false)
        {
            if (len == -1)
            {
                len = buffer.Length - offset;
            }
            if (copy)
            {
                byte[] destinationArray = new byte[len];
                Array.Copy(buffer, offset, destinationArray, 0, len);
                this.buffer = destinationArray;
                this.offset = 0;
                this.len = len;
            }
            else
            {
                this.buffer = buffer;
                this.offset = offset;
                this.len = len;
            }
        }

        public byte[] ToBuffer()
        {
            if ((this.offset == 0) && ((this.offset + this.len) == this.buffer.Length))
            {
                return this.buffer;
            }
            byte[] destinationArray = new byte[this.len];
            Array.Copy(this.buffer, this.offset, destinationArray, 0, this.len);
            return destinationArray;
        }

        public string HEXSTR
        {
            get
            {
                if (this.buffer == null)
                {
                    return string.Empty;
                }
                int len = this.len;
                if (len > 100)
                {
                    len = 100;
                }
                return BC.ToBCDString(this.buffer, this.offset, len, " ");
            }
        }

        [Browsable(false)]
        public bool IsDisposed
        {
            get
            {
                return (Interlocked.CompareExchange(ref this.disposedFlag, 1, 1) == 0);
            }
        }
    }
}

